#include "Camera.h"

#include <gtx/rotate_vector.hpp>

mat4 Camera::getView() {
	return lookAt(position, position + direction, up);
}

void Camera::moveForward(float step_size) {
	position += step_size * direction;	
}

void Camera::moveBackward(float step_size) {
	position -= step_size * direction;
}

void Camera::strafeLeft(float step_size) {
	position -= cross(direction, up) * step_size;
}

void Camera::strafeRight(float step_size) {
	position += cross(direction, up) * step_size;
}

void Camera::rotateLeft(float step_size) {
	direction = normalize(gtx::rotate_vector::rotate(direction, step_size, up));
}

void Camera::rotateRight(float step_size) {
	direction = normalize(gtx::rotate_vector::rotate(direction, -step_size, up));
}

void Camera::rotateUp(float step_size) {
	vec3 cp = cross(direction, up);
	vec3 newDirection = normalize(gtx::rotate_vector::rotate(direction, step_size, cp));

	// Prevent from rotating too close to the up vector
	if(fabs(dot(newDirection, up)) < .98)
		direction = newDirection;
}

void Camera::rotateDown(float step_size) {
	vec3 cp = cross(direction, up);
	vec3 newDirection = normalize(gtx::rotate_vector::rotate(direction, -step_size, cp));
	if(fabs(dot(newDirection, up)) < .98)
		direction = newDirection;
}

void Camera::moveUp(float step_size) {
	position += up*step_size;
}

vec3 Camera::getPosition() {
	return position;
}

vec3 Camera::getDirection() {
	return direction;
}